Revisited Version
This report Contain justification for selection of mathematical functions related to the model.
1.Upgrades done to the Model
2.System Design
3.Network architecture
4.Implementation
5.Results of the Model
6.Inference Model
Completely New set of Training and Testing Date were collected from the field (During the period when implementing the model paddy cultivations were not in a situation to collect data). They contain six different classes of paddy images which is shown in the System Design. New Training and Testing Set contains more than 4,000 images that were collected from different fields.
Due to an Error in the Code base, when generating Test set the images were taken from Train set directory. Therefore, after training the Model, It was tested using same training set, this caused giving accuracy as 100%. This has been fixed in the Revisited version of the Model.
To minimize the loss of image details the size of images that were used to train and test the Model was increased from 50px to 64px. (Ideal size is 500px or More, Limited to 64px due to Available performance in Training computer)
This model can identify 6 differentiations in paddy cultivations.
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
User can input a image/ which contains paddy, model will classify the image with percentages of above classifications.
Five-layer neural network, input layer 64x64x3= 12 288, output 6 (6 types which were mentioned in the System Design) Output labels uses one-hot encoding
| Layer | Dimensions |
|---|---|
| input layer-X | [TrainSet size, IMG_SIZExIMG_SIZEx3] |
| 1 layer | W1[IMG_SIZExIMG_SIZEx3, 200] + b1[200] Y1[TrainSet size, 200] |
| 2 layer | W2[200, 100] + b2[100] Y2[TrainSet size, 200] |
| 3 layer | W3[100, 60] + b3[60] Y3[TrainSet size, 200] |
| 4 layer | W4[60, 30] + b4[30] Y4[TrainSet size, 30] |
| 5 layer | W5[30, 6] + b5[6] |
| One-hot encoded label | Y5[TrainSet size, 6] |
Layer implementation can be found here

This application is based on visual classification of images. The Differences between classes are due to small changes of features in images. In neural networks when we have more hidden layers the model can inspect more features that are available in the images when classifying. To get the maximum usage out of this the image sizes should be reasonable, and they should not have loosened their features upon resizing or manipulation. Therefore the Selection of 5 layers for this model was decided considering, taking the maximum usage of available hardware resources for better inspection of features in the images.
This Model can be easily expandable for more classes and more Layers in future applications.
Label representation¶
Here are examples for each number, how each label is represented. These are the original pictures,
Generation of data set according to the above Lable representaion can be found here
One Hot Matrix (One hot encoding)¶
In deep learning we use y vector with numbers ranging from 0 to C-1, where C is the number of classes. If C is for example 4, then we have the following y vector which we will need to convert as follows:
In this model One Hot matrix technique is used for the encodeing of data.
Cost functions calculate the difference between actual value (a) and the expected value (E).
Also known as mean squared error (Error sum of squares), maximum likelihood, and sum squared error, this is defined as:
The gradient of this cost function with respect to the output of a neural network and some sample r is:

TensorFlow implementation- tf.losses.mean_squared_error

Also known as Bernoulli negative log-likelihood and Binary Cross-Entropy
The gradient of this cost function with respect to the output of a neural network and some sample r is:
TensorFlow implementation- tf.nn.sigmoid_cross_entropy_with_logits

This cost function requires choosing some parameter Ï„ that we think will give us the behavior we need. We have to try different numbers until we get a better result. When training a model, it is often recommended to lower the learning rate as the training progresses. This function applies an exponential decay function to a provided initial learning rate.

The gradient of this cost function with respect to the output of a neural network and some sample r is:
<img src="images\Report\Equations\exp2.png" alt="Alt text that describes the graphic" title="Title text"/ >
TensorFlow implementation-tf.train.exponential_decay

Cost function implementation can be found here










Softmax function is a more generalized version of Sigmoid function. Since Sigmoid gives better results for classifiers and can only be used for binary classifiers Softmax function was created. This is a very popular Activation function among data scientists. The softmax function would squeeze the outputs for each class between 0 and 1 and would also divide by the sum of the outputs. This essentially gives the probability of the input being in a class. It can be defined as :

Selected Activation functions and Why¶
Activation functions were selected based on logic and heuristics about them since there are no any rule of thumb to select them.
- Sigmoid functions and their combinations generally work better in the case of classifiers but statndered Sigmoid function is used for binary classifiers. Softmax is more generalized type of Sigmoid function where we can use them in multi class classifiers
- Sigmoids and tanh functions are avoided due to the vanishing gradient problem
- ReLU function is a general activation function and gives best results.
But ReLU function work their best only in hidden layers.
This project initially started with ReLU function and tested for others. Considering the F1 score, activation function combinations were selected as Follows (All combinations were tested under Cross-entropy cost):
| Layer | Activation Function |
|---|---|
| 1 layer | ReLU |
| 2 layer | ReLU |
| 3 layer | ReLU |
| 4 layer | ReLU |
| 5 layer | SoftMax |
Previous Activation function Combinations
| Layer | Activation Function |
|---|---|
| 1 layer | ReLU |
| 2 layer | Linear |
| 3 layer | ReLU |
| 4 layer | Linear |
| 5 layer | SoftMax |
| Layer | Activation Function |
|---|---|
| 1 layer | Linear |
| 2 layer | Linear |
| 3 layer | Linear |
| 4 layer | Linear |
| 5 layer | SoftMax |
Available tools to implement Neural networks¶
- MathLab
- Python
- Using numpy (Math library for Python)
- Using TensorFlow (Developed by Google)
From above selection Python was selected due to the availability of Python. This model should be able to run on SOC devices (System on Chip devices). Implementing the model using python helps to make changes easily to run on different platforms.
This Model was initially developed with only using numpy and the source code is available commented on this Report.
The Main reason to move on to the TensorFlow is it has Cuda implementation where the model can be run on the GPU much faster than the CPU. TensorFlow has lot of built in features that supports for Neural networks
Results of the Model for Custom images can be found from here
Inference is used for Save the Parameters. By Saving trained parameters we do not need to run the program each time when we want to use the model. Using Inference Model an Android app was created. Inference of the Model can be found from here
import math
import numpy as np
import h5py
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.python.framework import ops
from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib
from tf_utils import load_dataset, random_mini_batches, convert_to_one_hot# predict
import os
%matplotlib inline
IMG_SIZE=64
import numpy as np
import h5py
import scipy
import skimage
from PIL import Image
from scipy import ndimage
from tqdm import tqdm
import os
import matplotlib.pyplot as plt
from skimage import transform
TRAIN_DIR='images/DataSet'
TEST_DIR='images/TestSet'
IMG_SIZE=64
def label_img(img):
word_label=img.split(' ')
if word_label[0]=='Healthy':
return 0
elif word_label[0]=='LowFertile':
return 1
elif word_label[0]=='WeedType1':
return 2
elif word_label[0]=='WeedType2':
return 3
elif word_label[0]=='WeedType3':
return 4
elif word_label[0]=='WeedType4':
return 5
def generateTrainSet():
hf = h5py.File('images/temp/train_plants.h5', 'w')
d1 = []
d2 = []
for img in tqdm(os.listdir(TRAIN_DIR)):
label=label_img(img)
fname = os.path.join(TRAIN_DIR,img)
#print (fname)
image = np.array(plt.imread(fname))
my_image =skimage.transform.resize(image, (IMG_SIZE,IMG_SIZE))#.reshape((1, IMG_SIZE*IMG_SIZE*3)).T
d1.append(my_image)
d2.append(label)
#print (d1.shape, d2.shape)
d1=np.array(d1)
d2=np.array(d2)
hf.create_dataset('train_set_x', data=d1)
hf.create_dataset('train_set_y', data=d2)
hf.close()
def generateTestSet():
hf = h5py.File('images/temp/test_plants.h5', 'w')
d1 = []
d2 = []
for img in tqdm(os.listdir(TEST_DIR)):
label=label_img(img)
fname = os.path.join(TEST_DIR,img)
image = np.array(plt.imread(fname))
my_image = skimage.transform.resize(image,(IMG_SIZE,IMG_SIZE))#.reshape((1, IMG_SIZE*IMG_SIZE*3)).T
d1.append(my_image)
d2.append(label)
#print (d1.shape, d2.shape)
d1=np.array(d1)
d2=np.array(d2)
classes=np.array([0,1,2,3,4,5])
hf.create_dataset('test_set_x', data=d1)
hf.create_dataset('test_set_y', data=d2)
hf.create_dataset('list_classes', data=classes)
hf.close()
generateTrainSet()
generateTestSet()
def one_hot_matrix(labels, C):
C = tf.constant(C, name="C")
# Use tf.one_hot
one_hot_matrix = tf.one_hot(labels, depth=C, axis=0)
# Create the session
sess = tf.Session()
one_hot = sess.run(one_hot_matrix)
# Close the session
sess.close()
return one_hot
def load_dataset():
train_dataset = h5py.File('datasets/train_plants.h5', "r")
train_set_x_orig = np.array(train_dataset["train_set_x"][:]) #train set features
train_set_y_orig = np.array(train_dataset["train_set_y"][:]) #train set labels
test_dataset = h5py.File('datasets/test_plants.h5', "r")
test_set_x_orig = np.array(test_dataset["test_set_x"][:]) #test set features
test_set_y_orig = np.array(test_dataset["test_set_y"][:]) #test set labels
classes = np.array(test_dataset["list_classes"][:]) # the list of classes
train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
def random_mini_batches(X, Y, mini_batch_size = 64, seed = 0):
m = X.shape[1] # number of training examples
mini_batches = []
np.random.seed(seed)
# Step 1: Shuffle (X, Y)
permutation = list(np.random.permutation(m))
shuffled_X = X[:, permutation]
shuffled_Y = Y[:, permutation].reshape((Y.shape[0],m))
# Step 2: Partition (shuffled_X, shuffled_Y). Minus the end case.
num_complete_minibatches = math.floor(m/mini_batch_size) # number of mini batches of size mini_batch_size in your partitionning
for k in range(0, num_complete_minibatches):
mini_batch_X = shuffled_X[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size]
mini_batch_Y = shuffled_Y[:, k * mini_batch_size : k * mini_batch_size + mini_batch_size]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
# Handling the end case (last mini-batch < mini_batch_size)
if m % mini_batch_size != 0:
mini_batch_X = shuffled_X[:, num_complete_minibatches * mini_batch_size : m]
mini_batch_Y = shuffled_Y[:, num_complete_minibatches * mini_batch_size : m]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
return mini_batches
def convert_to_one_hot(Y, C):
Y = np.eye(C)[Y.reshape(-1)].T
return Y
# Loading the dataset
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()
# Example picture of data set
index = 400
plt.imshow(X_train_orig[index])
print ("y = " + str(np.squeeze(Y_train_orig[:, index])))
# Flatten the training and test images
X_train_flatten = X_train_orig.reshape(X_train_orig.shape[0], -1).T
X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0], -1).T
# Normalize image vectors
X_train = X_train_flatten/255.
X_test = X_test_flatten/255.
# Convert training and test labels to one hot matrices
Y_train = convert_to_one_hot(Y_train_orig, 6)
Y_test = convert_to_one_hot(Y_test_orig, 6)
def compute_cost(Z3, Y): #Implemented with different cost functions
"""
Computes the cost
2 types cost functions have been implemented here for training
"""
# to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...)
logits = tf.transpose(Z3)
labels = tf.transpose(Y)
#cost =tf.reduce_mean(tf.losses.mean_squared_error(labels=labels,predictions=logits))
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels))
return cost
IMG_SIZE=64
learning_rate = 0.0001
num_epochs = 1500
print_cost = True
minibatch_size = 32
import time
start=time.time()
ops.reset_default_graph() # to be able to rerun the model without overwriting tf variables
tf.set_random_seed(1) # to keep consistent results
seed = 3 # to keep consistent results
(n_x, m) = X_train.shape # (n_x: input size, m : number of examples in the train set)
n_y = Y_train.shape[0] # n_y : output size
costs = [] # To keep track of the cost
# Create Placeholders of shape (n_x, n_y)
X = tf.placeholder(tf.float32,[n_x,None],name="X")
Y = tf.placeholder(tf.float32,[n_y,None],name="Y")
# Initialize parameters
#W1 = tf.get_variable("W1", [25,IMG_SIZE*IMG_SIZE*3], initializer = tf.contrib.layers.xavier_initializer())
#b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())
#W2 = tf.get_variable("W2", [12,25], initializer = tf.contrib.layers.xavier_initializer())
#b2 = tf.get_variable("b2", [12,1], initializer = tf.zeros_initializer())
#W3 = tf.get_variable("W3", [6,12], initializer = tf.contrib.layers.xavier_initializer())
#b3 = tf.get_variable("b3", [6,1], initializer = tf.zeros_initializer())
L1 = 200
L2 = 100
L3 = 60
L4 = 30
L5 = 6
W1 = tf.Variable(tf.truncated_normal([L1,IMG_SIZE*IMG_SIZE*3], stddev=0.1))
b1 = tf.Variable(tf.zeros([L1,1]))
W2 = tf.Variable(tf.truncated_normal([L2,L1], stddev=0.1))
b2 = tf.Variable(tf.zeros([L2,1]))
W3 = tf.Variable(tf.truncated_normal([L3,L2], stddev=0.1))
b3 = tf.Variable(tf.zeros([L3,1]))
W4 = tf.Variable(tf.truncated_normal([L4,L3], stddev=0.1))
b4 = tf.Variable(tf.zeros([L4,1]))
W5 = tf.Variable(tf.truncated_normal([L5,L4], stddev=0.1))
b5 = tf.Variable(tf.zeros([L5,1]))
parameters = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2,
"W3": W3,
"b3": b3,
"W4": W4,
"b4": b4,
"W5": W5,
"b5": b5
}
phconst = tf.placeholder(tf.float32)
# Numpy Equivalents:
#Z1 = tf.add(tf.matmul(W1, X), b1) # Z1 = np.dot(W1, X) + b1
#A1 = tf.nn.relu(Z1) # A1 = relu(Z1)
#Z2 = tf.add(tf.matmul(W2, A1), b2) # Z2 = np.dot(W2, a1) + b2
#A2 = tf.nn.relu(Z2) # A2 = relu(Z2)
#Z3 = tf.add(tf.matmul(W3, A2), b3,name='output') # Z3 = np.dot(W3,Z2) + b3
A1 = tf.nn.leaky_relu(tf.matmul(W1,X) + b1)
#A1 = tf.nn.dropout(A1, phconst)
A2 = tf.nn.relu(tf.matmul(W2,A1) + b2)
#A2 = tf.nn.dropout(A2, phconst)
A3 = tf.nn.leaky_relu(tf.matmul(W3,A2) + b3)
#A3 = tf.nn.dropout(A3, phconst)
A4 = tf.nn.relu(tf.matmul(W4,A3) + b4)
#A4 = tf.nn.dropout(A4, phconst)
Alogits = tf.matmul(W5,A4) + b5
#Z5 = tf.nn.softmax(Alogits,name='output')
# Cost function: Add cost function to tensorflow graph
cost = compute_cost(Alogits, Y)
# Backpropagation: Define the tensorflow optimizer. Using AdamOptimizer.
optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)
# Initialize all the variables
init = tf.global_variables_initializer()
# Start the session to compute the tensorflow graph
with tf.Session() as sess:
# Run the initialization
sess.run(init)
# Do the training loop
for epoch in range(num_epochs):
epoch_cost = 0. # Defines a cost related to an epoch
num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set
seed = seed + 1
minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)
for minibatch in minibatches:
# Select a minibatch
(minibatch_X, minibatch_Y) = minibatch
# IThe line that runs the graph on a minibatch.
# Run the session to execute the "optimizer" and the "cost", the feedict should contain a minibatch for (X,Y).
_ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})
epoch_cost += minibatch_cost / num_minibatches
# Print the cost every epoch
if print_cost == True and epoch % 100 == 0:
print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
if print_cost == True and epoch % 5 == 0:
costs.append(epoch_cost)
# plot the cost
plt.plot(np.squeeze(costs))
plt.ylabel('cost')
plt.xlabel('iterations (per tens)')
plt.title("Learning rate =" + str(learning_rate))
plt.show()
# lets save the parameters in a variable
#parameters = sess.run(parameters)
print ("Parameters have been trained!")
# Calculate the correct predictions
correct_prediction = tf.equal(tf.argmax(Alogits), tf.argmax(Y))
# Calculate accuracy on the test set
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))
parameters = sess.run(parameters)
saver = tf.train.Saver()
#sess = tf.InteractiveSession()
#init = tf.global_variables_initializer()
g = tf.get_default_graph()
# every operations in our graph
[op.name for op in g.get_operations()]
#saver = tf.train.Saver()
model_directory='model_files/'
if not os.path.exists(model_directory):
os.makedirs(model_directory)
#saving the graph
tf.train.write_graph(sess.graph_def, model_directory, 'savegraph.pbtxt')
saver.save(sess, 'model_files/model.ckpt')
np.save('parameters.npy',parameters)
print (time.time()-start)
#saver = tf.train.Saver()
model_directory='model_files/'
if not os.path.exists(model_directory):
os.makedirs(model_directory)
#saving the graph
tf.train.write_graph(sess.graph_def, model_directory, 'savegraph.pbtxt')
# Freeze the graph
MODEL_NAME = 'paddy'
input_graph_path = 'model_files/savegraph.pbtxt'
checkpoint_path = 'model_files/model.ckpt'
input_saver_def_path = ""
input_binary = False
output_node_names = "output"
restore_op_name = "save/restore_all"
filename_tensor_name = "save/Const:0"
output_frozen_graph_name = 'model_files/frozen_model_'+MODEL_NAME+'.pb'
output_optimized_graph_name = 'model_files/optimized_inference_model_'+MODEL_NAME+'.pb'
clear_devices = True
freeze_graph.freeze_graph(input_graph_path, input_saver_def_path,
input_binary, checkpoint_path, output_node_names,
restore_op_name, filename_tensor_name,
output_frozen_graph_name, clear_devices, "")
output_graph_def = optimize_for_inference_lib.optimize_for_inference(
sess.graph_def,
["X"], # an array of the input node(s)
["output"], # an array of output nodes
tf.float32.as_datatype_enum)
#output_graph_def
with tf.gfile.GFile(output_optimized_graph_name, "wb") as f:
f.write(output_graph_def.SerializeToString())
#g = tf.GraphDef()
##checking frozen graph
#g.ParseFromString(open(output_optimized_graph_name, 'rb').read())
#g
#g1 = tf.GraphDef()
##checking frozen graph
#g1.ParseFromString(open("./model_files/frozen_model_paddy.pb", 'rb').read())
#g1
def forward_propagation(X, parameters):
# Numpy Equivalents:
#Z1 = tf.add(tf.matmul(W1, X), b1) # Z1 = np.dot(W1, X) + b1
#A1 = tf.nn.relu(Z1) # A1 = relu(Z1)
#Z2 = tf.add(tf.matmul(W2, A1), b2) # Z2 = np.dot(W2, a1) + b2
#A2 = tf.nn.relu(Z2) # A2 = relu(Z2)
#Z3 = tf.add(tf.matmul(W3, A2), b3,name='output') # Z3 = np.dot(W3,Z2) + b3
# Retrieve the parameters from the dictionary "parameters"
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']
W3 = parameters['W3']
b3 = parameters['b3']
W4 = parameters['W4']
b4 = parameters['b4']
W5 = parameters['W5']
b5 = parameters['b5']
# Numpy Equivalents:
#Z1 = tf.add(tf.matmul(W1,X),b1) # Z1 = np.dot(W1, X) + b1
#A1 = tf.nn.relu(Z1) # A1 = relu(Z1)
#Z2 = tf.add(tf.matmul(W2,A1),b2) # Z2 = np.dot(W2, a1) + b2
#A2 = tf.nn.relu(Z2) # A2 = relu(Z2)
#Z3 = tf.add(tf.matmul(W3,A2),b3) # Z3 = np.dot(W3,Z2) + b3
A1 = tf.nn.relu(tf.matmul(W1,X) + b1)
#A1 = tf.nn.dropout(A1, phconst)
A2 = tf.nn.relu(tf.matmul(W2,A1) + b2)
#A2 = tf.nn.dropout(A2, phconst)
A3 = tf.nn.relu(tf.matmul(W3,A2) + b3)
#A3 = tf.nn.dropout(A3, phconst)
A4 = tf.nn.relu(tf.matmul(W4,A3) + b4)
#A4 = tf.nn.dropout(A4, phconst)
Alogits = tf.matmul(W5,A4) + b5
Z5 = tf.nn.softmax(Alogits,name='output')
return Alogits
def predict(X, parameters):
W1 = tf.convert_to_tensor(parameters["W1"])
b1 = tf.convert_to_tensor(parameters["b1"])
W2 = tf.convert_to_tensor(parameters["W2"])
b2 = tf.convert_to_tensor(parameters["b2"])
W3 = tf.convert_to_tensor(parameters["W3"])
b3 = tf.convert_to_tensor(parameters["b3"])
W4 = tf.convert_to_tensor(parameters["W4"])
b4 = tf.convert_to_tensor(parameters["b4"])
W5 = tf.convert_to_tensor(parameters["W5"])
b5 = tf.convert_to_tensor(parameters["b5"])
params = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2,
"W3": W3,
"b3": b3,
"W4": W4,
"b4": b4,
"W5": W5,
"b5": b5
}
x = tf.placeholder("float", [12288, 1])
z5 = forward_propagation(x, params)
p = tf.argmax(z5)
with tf.Session() as sess:
prediction = sess.run(p, feed_dict = {x: X})
return prediction
def picType(n):
if n==0:
return 'Healthy'
elif n==1:
return 'Low fertile soil'
elif n==2:
return 'Weed type 1'
elif n==3:
return 'Weed type 2'
elif n==4:
return 'Weed type 3'
elif n==5:
return 'Weed type 4'
import scipy
from PIL import Image
from scipy import ndimage
import numpy as np
import os
from tqdm import tqdm
import time
IMG_SIZE=64
DEMO_DIR = "images/Demo"
loaded_data=np.load('parameters.npy')
parameters = {"W1": loaded_data.item().get('W1'),
"b1": loaded_data.item().get('b1'),
"W2": loaded_data.item().get('W2'),
"b2": loaded_data.item().get('b2'),
"W3": loaded_data.item().get('W3'),
"b3": loaded_data.item().get('b3'),
"W4": loaded_data.item().get('W4'),
"b4": loaded_data.item().get('b4'),
"W5": loaded_data.item().get('W5'),
"b5": loaded_data.item().get('b5')}
for img in os.listdir(DEMO_DIR):
fname = os.path.join(DEMO_DIR,img)
image = np.array(ndimage.imread(fname, flatten=False))
startTime=time.time()
my_image= scipy.misc.imresize(image, size=(IMG_SIZE,IMG_SIZE)).reshape((1, IMG_SIZE*IMG_SIZE*3)).T
my_image_prediction = predict(my_image, parameters)
print (time.time()-startTime)
plt.imshow(image)
plt.pause(0.0001)
print(my_image_prediction)
print("Algorithm predicts image is " + picType(np.squeeze(my_image_prediction))+" for Image "+str(img))